#include <iostream>
#include <vector>
#include <cmath>
#include <map>
#include <fstream>
#include <algorithm>

// 建筑常量
const int FLOOR_HEIGHT = 3;
const double BUILDING_SIZE[3] = {100.0, 80.0, FLOOR_HEIGHT * 3.5};
const double CLASSROOM_SIZE[2] = {15.0, 10.0};

// 墙体类型
enum WallType
{
    LOAD_BEARING = 12, // 承重墙12dB
    PARTITION = 6,     // 隔断墙6dB
    GLASS = 7          // 玻璃幕墙7dB
};

// AP结构体
struct AP
{
    double pos[3];   // (x,y,z)坐标
    int channel_2G;  // 2.4GHz信道
    int channel_5G;  // 5GHz信道
    double power_2G; // 发射功率(dBm)
    double power_5G;
};

// 信号衰减计算
double calculateAttenuation(const AP &ap, const double point[3],
                            const std::vector<WallType> &walls)
{
    // 三维距离计算
    double dx = ap.pos[0] - point[0];
    double dy = ap.pos[1] - point[1];
    double dz = ap.pos[2] - point[2];
    double distance = sqrt(dx * dx + dy * dy + dz * dz);

    // 自由空间损耗
    double fs_loss = 32.5 + 20 * log10(2400) + 20 * log10(distance / 1000);

    // 墙体衰减
    double wall_loss = 0;
    for (const auto &wall : walls)
    {
        wall_loss += static_cast<double>(wall);
    }

    return fs_loss + wall_loss;
}

// 墙体追踪（简化实现）
std::vector<WallType> traceWalls(const double start[3], const double end[3])
{
    // 实际应用应结合建筑结构数据
    return {LOAD_BEARING, PARTITION}; // 示例返回值
}

// 遗传算法优化占位
void optimizeAPPlacement(std::vector<AP> &aps)
{
    // 走廊部署初始方案
    for (double z = 0; z < BUILDING_SIZE[2]; z += 3.5)
    {
        for (double x = 0; x < BUILDING_SIZE[0]; x += 15.0)
        {
            AP newAP = {x, BUILDING_SIZE[1] / 2, z, 0, 0, 20.0, 27.0};
            aps.push_back(newAP);
        }
    }
}

// 信道分配
void assignChannels(std::vector<AP> &aps)
{
    // 2.4GHz信道分配
    std::vector<int> channels2G = {1, 6, 11};
    for (size_t i = 0; i < aps.size(); ++i)
    {
        aps[i].channel_2G = channels2G[i % 3];
    }

    // 5GHz信道分配
    std::vector<int> channels5G;
    for (int ch = 36; ch <= 165; ch += 4)
    {
        channels5G.push_back(ch);
    }
    for (size_t i = 0; i < aps.size(); ++i)
    {
        aps[i].channel_5G = channels5G[i % channels5G.size()];
    }
}

// 热力图生成
void generateHeatmap(const std::vector<AP> &aps)
{
    const int RESOLUTION = 1;
    std::vector<std::vector<double>> heatmap(
        BUILDING_SIZE[0],
        std::vector<double>(BUILDING_SIZE[1], -100.0));

    for (int x = 0; x < BUILDING_SIZE[0]; ++x)
    {
        for (int y = 0; y < BUILDING_SIZE[1]; ++y)
        {
            double point[3] = {x + 0.5, y + 0.5, 1.75};
            double maxStrength = -100.0;

            for (const auto &ap : aps)
            {
                auto walls = traceWalls(ap.pos, point);
                double atten = calculateAttenuation(ap, point, walls);
                double strength = ap.power_2G - atten;
                maxStrength = std::max(maxStrength, strength);
            }

            heatmap[x][y] = maxStrength;
        }
    }

    // 输出热力图
    std::ofstream file("heatmap.csv");
    for (const auto &row : heatmap)
    {
        for (double val : row)
        {
            file << val << ",";
        }
        file << "\n";
    }
}

int main()
{
    std::vector<AP> aps;

    // 优化AP部署
    optimizeAPPlacement(aps);

    // 分配信道
    assignChannels(aps);

    // 生成热力图
    generateHeatmap(aps);

    // 输出结果
    std::cout << "部署AP数量: " << aps.size() << std::endl;
    for (size_t i = 0; i < aps.size(); ++i)
    {
        const auto &ap = aps[i];
        std::printf("AP%d 位置: (%.1f, %.1f, %.1f) 信道: 2G-Ch%d / 5G-Ch%d\n",
                    i + 1, ap.pos[0], ap.pos[1], ap.pos[2],
                    ap.channel_2G, ap.channel_5G);
    }
    std::cout << "热力图已生成至heatmap.csv" << std::endl;

    return 0;
}